package top.tungsword.webconsole.dal;


import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import javax.sql.DataSource;

/**
 * @author chenji.yu
 * @date 2020/4/16 18:34
 * @description
 * 使用springMybatis配置数据源，参考官网：http://mybatis.org/spring/zh/index.html
 *
 * 多个数据源配置，在配置一个DataSourceConfig，将basePackages和sqlSessionFactoryRef配置与当前不相同
 */
@Configuration
//自动扫描映射文件
@MapperScan(basePackages = "top.tungsword.webconsole.dal.mapper", sqlSessionFactoryRef = "sqlSessionFactory")
public class DataSourceConfig {
    @Value("${jdbc_driver_class:com.mysql.cj.jdbc.Driver}")
    private String jdbcDriverClass;

    @Value("${jdbc_url:jdbc:mysql://10.1.0.11:3306/test?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true}")
    private String jdbcUrl;

    @Value("${jdbc_username:root}")
    private String jdbcUsername;

    @Value("${jdbc_password:Root@123}")
    private String jdbcPassword;

    @Value("${minimumIdle:3}")
    private int minimumIdle;

    @Value("${maxPoolSize:10}")
    private int maxPoolSize;

    @Value("${connectionTestQuery:select 1 from dual}")
    private String connectionTestQuery;

    @Value("${validationTimeout:5000}")
    private long validationTimeout;

    @Value("${maxLifetime:600000}")
    private long maxLifetime;

    @Value("${connectionTimeout:300000}")
    private long connectionTimeout;

    @Value("${readOnly:false}")
    private boolean readOnly;

    @Value("${idleTimeout:600000}")
    private long idleTimeout;

    @Value("${mapper_location:classpath*:mybatis_mapper/*.xml}")
    private String mapperLocation;

    @Bean
    public DataSource dataSource() {
        HikariConfig jdbcConfig = new HikariConfig();

        //连接池名称，用于日志打印
        jdbcConfig.setPoolName(getClass().getName());
        //数据库连接配置
        jdbcConfig.setJdbcUrl(jdbcUrl);
        jdbcConfig.setUsername(jdbcUsername);
        jdbcConfig.setPassword(jdbcPassword);
        jdbcConfig.setDriverClassName(jdbcDriverClass);

        // 一个连接的生命时长（毫秒），超时而且没被使用则被释放
        // 建议设置比数据库超时时长少30秒，参考MySQL wait_timeout参数（show variables like '%timeout%';）
        jdbcConfig.setMaxLifetime(maxLifetime);

        // 一个连接idle状态的最大时长（毫秒），超时则被释放
        jdbcConfig.setIdleTimeout(idleTimeout);

        // 最小空闲连接数
        jdbcConfig.setMinimumIdle(minimumIdle);

        // 最大连接数，推荐的公式：((core_count * 2) + effective_spindle_count)
        jdbcConfig.setMaximumPoolSize(maxPoolSize);

        // 等待连接池分配连接的最大时长（毫秒），超过这个时长还没可用的连接则发生SQLException
        jdbcConfig.setConnectionTimeout(connectionTimeout);

        // 是否只读，连接只读数据库时配置为true
        jdbcConfig.setReadOnly(readOnly);

        // 连接心跳测试语句
        jdbcConfig.setConnectionTestQuery(connectionTestQuery);

        //连接的心跳检查间隔（毫秒）
        jdbcConfig.setValidationTimeout(validationTimeout);
        return new HikariDataSource(jdbcConfig);
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //配置数据源
        sqlSessionFactoryBean.setDataSource(dataSource());
        //加载mybatis文件
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resourceResolver.getResources(mapperLocation));
        return sqlSessionFactoryBean.getObject();
    }

}
